package com.centaline.androidsalesblog.fragments;

import android.app.Activity;
import android.content.Intent;
import android.support.v7.widget.AppCompatTextView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.android.volley.VolleyError;
import com.centaline.androidsalesblog.R;
import com.centaline.androidsalesblog.activities.news.ChatActivity;
import com.centaline.androidsalesblog.activities.news.EstateNewsActivity;
import com.centaline.androidsalesblog.adapter.ConversationAdapter;
import com.centaline.androidsalesblog.adapter.viewholder.ConversationVH;
import com.centaline.androidsalesblog.api.sale.EsfEstateListApi;
import com.centaline.androidsalesblog.api.sale.PostListApi;
import com.centaline.androidsalesblog.api.usercenter.CollectInfoChangeApi;
import com.centaline.androidsalesblog.base.BaseFragment;
import com.centaline.androidsalesblog.constants.AppConstant;
import com.centaline.androidsalesblog.constants.CommonConstant;
import com.centaline.androidsalesblog.constants.ExtraConstant;
import com.centaline.androidsalesblog.constants.SprfConstant;
import com.centaline.androidsalesblog.events.ConversationUpdate;
import com.centaline.androidsalesblog.events.JPushMessage;
import com.centaline.androidsalesblog.events.RongConnectStatus;
import com.centaline.androidsalesblog.events.RongReceiveMessage;
import com.centaline.androidsalesblog.events.UserOperate;
import com.centaline.androidsalesblog.fragments.list.EsfNewsFragment;
import com.centaline.androidsalesblog.fragments.list.PostNewsFragment;
import com.centaline.androidsalesblog.iml.RecyclerViewItemOnClickListener;
import com.centaline.androidsalesblog.iml.RongUserInfoProvider;
import com.centaline.androidsalesblog.model.businissobject.CollectInfoChangeBo;
import com.centaline.androidsalesblog.model.businissobject.RongUserInfoBo;
import com.centaline.androidsalesblog.model.databaseobject.BizUnitDo;
import com.centaline.androidsalesblog.model.databaseobject.EsfEstateDo;
import com.centaline.androidsalesblog.model.databaseobject.PostDo;
import com.centaline.androidsalesblog.model.databaseobject.StaffDo;
import com.centaline.androidsalesblog.model.responseobject.CollectInfoChangeRo;
import com.centaline.androidsalesblog.model.responseobject.EsfEstateListRo;
import com.centaline.androidsalesblog.model.responseobject.PostListRo;
import com.centaline.androidsalesblog.rx.database.RxDataBase;
import com.centaline.androidsalesblog.rx.request.RxRequest;
import com.centaline.androidsalesblog.utils.DateUtil;
import com.centaline.androidsalesblog.utils.RongUserIdUtil;
import com.centanet.framework.glide.GlideLoad;
import com.centanet.framework.interfaces.IResponseListener;
import com.centanet.framework.utils.SprfUtil;
import com.trello.rxlifecycle.FragmentEvent;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import io.rong.imlib.RongIMClient;
import io.rong.imlib.model.Conversation;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;


/**
 * 动态
 */
public class NewsFragment extends BaseFragment implements View.OnClickListener {

    private Toolbar toolbar;
    private RelativeLayout rl_news;
    private ImageView img_news_point;
    private AppCompatTextView atv_news_desc, atv_date;
    private RecyclerView rv_conversation;

    private ArrayList<Conversation> conversationList = new ArrayList<>();
    private ConversationAdapter adapter;
    private CollectInfoChangeApi collectInfoChangeApi;
    private ArrayList<CollectInfoChangeBo> collectInfoChangeBos = new ArrayList<>();
    private PostListApi postListApi;
    private String time;
    private String roomCount;
    private String postName;
    private String price;
    private int index;
    private EsfEstateListApi esfEstateListApi;
    private String estateName;
    private boolean isRead = true;

    @Override
    protected int setLayoutId() {
        return R.layout.fragment_news;
    }

    @Override
    protected void findViews(View view) {
        toolbar = (Toolbar) view.findViewById(R.id.toolbar);
        rl_news = (RelativeLayout) view.findViewById(R.id.rl_news);
        img_news_point = (ImageView) view.findViewById(R.id.img_news_point);
        atv_news_desc = (AppCompatTextView) view.findViewById(R.id.atv_news_desc);
        atv_date = (AppCompatTextView) view.findViewById(R.id.atv_date);
        rv_conversation = (RecyclerView) view.findViewById(R.id.rv_conversation);
    }

    @Override
    protected void initView() {
        toolbar.setTitle(R.string.main_tab_news);
        img_news_point.setVisibility(SprfUtil.getBoolean(getContext(),
                String.format(Locale.CHINA, "%s_%s", AppConstant.CityCode, SprfConstant.JPUSH_NEW_MESSAGE), false)
                ? View.VISIBLE : View.GONE);
        rl_news.setOnClickListener(this);
        rv_conversation.setLayoutManager(new LinearLayoutManager(getContext()));
        adapter = new ConversationAdapter(getContext(), GlideLoad.initRound(this), conversationList,
                new RecyclerViewItemOnClickListener<Conversation>() {
                    @Override
                    public void onItemOnClick(Conversation conversation, int tag) {
                        startActivity(new Intent(getActivity(), ChatActivity.class)
                                .putExtra(ExtraConstant.TargetId, conversation.getTargetId()));
                    }
                });
        adapter.setRongUserInfoProvider(new RongUserInfoProvider() {
            @Override
            public void provide(String targetId, final int position) {
                Observable.concat(RxDataBase.rongUserInfo(targetId)
                                .subscribeOn(Schedulers.io()),
                        RxRequest.rongUserInfo(ChatActivity.class, targetId)
                                .map(new Func1<StaffDo, RongUserInfoBo>() {
                                    @Override
                                    public RongUserInfoBo call(StaffDo staffDo) {
                                        saveTargetStaff(staffDo);
                                        if (staffDo == null) {
                                            return null;
                                        } else {
                                            return new RongUserInfoBo(RongUserIdUtil.getSatffId(staffDo.getStaffNo()),
                                                    staffDo.getCnName(),
                                                    staffDo.getImgUrl(),
                                                    staffDo.getMobile());
                                        }
                                    }
                                }))
                        .first()
                        .compose(NewsFragment.this.<RongUserInfoBo>bindUntilEvent(FragmentEvent.DESTROY))
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Action1<RongUserInfoBo>() {
                            @Override
                            public void call(RongUserInfoBo rongUserInfoBo) {
                                if (rongUserInfoBo != null) {
                                    adapter.putUserInfo(position, rongUserInfoBo);
                                }
                            }
                        });
            }
        });
        rv_conversation.setHasFixedSize(true);
        rv_conversation.setAdapter(adapter);

        ItemTouchHelper.Callback callback = new ItemTouchHelper.Callback() {
            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                return makeMovementFlags(ItemTouchHelper.ACTION_STATE_IDLE, ItemTouchHelper.START);
            }

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                clearMessage(conversationList.get(viewHolder.getAdapterPosition()).getTargetId());
                adapter.delete(viewHolder.getAdapterPosition());
            }

            @Override
            public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                super.clearView(recyclerView, viewHolder);
                ConversationVH conversationVH = (ConversationVH) viewHolder;
                conversationVH.itemView.setBackgroundResource(R.drawable.ic_table_normal);
            }

            @Override
            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
                if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
                    ConversationVH conversationVH = (ConversationVH) viewHolder;
                    conversationVH.itemView.setBackgroundResource(R.drawable.ic_table_selected);
                }
                super.onSelectedChanged(viewHolder, actionState);
            }
        };

        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
        itemTouchHelper.attachToRecyclerView(rv_conversation);
        checkConversation();
        EventBus.getDefault().register(this);

        collectInfoChangeApi = new CollectInfoChangeApi(PostNewsFragment.class,
                CollectInfoChangeRo.class, new
                IResponseListener<CollectInfoChangeRo>() {
                    @Override
                    public void onResponse(CollectInfoChangeRo collectInfoChangeRo) {
                        index = 0;
                        collectInfoChangeBos.clear();
                        if (collectInfoChangeRo.getCollectInfoChangeBos() != null &&
                                collectInfoChangeRo.getCollectInfoChangeBos().size() > 0) {
                            collectInfoChangeBos.addAll(collectInfoChangeRo.getCollectInfoChangeBos());
                        }
                        if (collectInfoChangeBos.size() == 0) {
                            atv_news_desc.setText("");
                            atv_date.setText("");
                            snack(collectInfoChangeRo.getMessage());
                        } else {
                            isRead = true;
                            for (CollectInfoChangeBo collectInfoChangeBo : collectInfoChangeBos) {
                                if (!collectInfoChangeBo.isRead()) {
                                    img_news_point.setVisibility(View.VISIBLE);
                                    isRead = false;
                                }
                            }
                            if(getActivity()!=null){
                                SprfUtil.setBoolean(getActivity(), String.format(Locale.CHINA, "%s_%s", AppConstant.CityCode, SprfConstant.JPUSH_NEW_MESSAGE), !isRead);
                                EventBus.getDefault().post(new JPushMessage("tomain"));
                            }
                            img_news_point.setVisibility(!isRead? View.VISIBLE : View.GONE);
                            if ("estcount".equalsIgnoreCase(collectInfoChangeBos.get(0).getChangeType())) {
                                time = DateUtil.timeRule(collectInfoChangeBos.get(0).getUpdateTime2() * 1000);
                                esfEstateListApi.setCestcodes(collectInfoChangeBos.get(0).getCollectInfoBo().getCollectValue());
                                esfEstateListApi.startRequest();
                            } else {
                                time = DateUtil.timeRule(collectInfoChangeBos.get(0).getUpdateTime2() * 1000);
                                price = priceTransformate(0);
                                postListApi.setPostIds(collectInfoChangeBos.get(0).getCollectInfoBo().getCollectValue());
                                postListApi.startRequest();
                            }
                        }
                    }

                    @Override
                    public void onErrorResponse(VolleyError error) {

                    }
                });
        collectInfoChangeApi.startRequest();

        postListApi = new PostListApi(PostNewsFragment.class, PostListRo.class, new IResponseListener<PostListRo>() {
            @Override
            public void onResponse(PostListRo postListRo) {
                ArrayList<PostDo> postDos = postListRo.getList();
                if (postDos == null || postDos.size() == 0) {
                    if (index < collectInfoChangeBos.size() - 1) {
                        index++;
                        if ("estcount".equalsIgnoreCase(collectInfoChangeBos.get(index).getChangeType())) {
                            time = DateUtil.timeRule(collectInfoChangeBos.get(index).getUpdateTime2() * 1000);
                            esfEstateListApi.setCestcodes(collectInfoChangeBos.get(index).getCollectInfoBo().getCollectValue());
                            esfEstateListApi.setType("");
                            esfEstateListApi.setPosttype("");
                            esfEstateListApi.startRequest();
                        } else {
                            time = DateUtil.timeRule(collectInfoChangeBos.get(index).getUpdateTime2() * 1000);
                            price = priceTransformate(index);
                            postListApi.setPostIds(collectInfoChangeBos.get(index).getCollectInfoBo().getCollectValue());
                            postListApi.startRequest();
                        }
                    } else {
                        atv_news_desc.setText("");
                        atv_date.setText("");
                    }
                } else {
                    PostDo postDo = postDos.get(0);
                    roomCount = String.format(Locale.CHINA, "%d室%d厅", postDo.getBedroomCount(), postDo.getSittingRoomCount());
                    postName = postDo.getCnEstate();
                    refreshDynamic();
                }
            }

            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });

        esfEstateListApi = new EsfEstateListApi(EsfNewsFragment.class, EsfEstateListRo.class, new IResponseListener<EsfEstateListRo>() {
            @Override
            public void onResponse(EsfEstateListRo esfEstateListRo) {
                ArrayList<EsfEstateDo> esfEstateDos = esfEstateListRo.getList();
                if (esfEstateDos == null || esfEstateDos.size() == 0) {
                    if (index < collectInfoChangeBos.size() - 1) {
                        index++;
                        if ("estcount".equalsIgnoreCase(collectInfoChangeBos.get(index).getChangeType())) {
                            time = DateUtil.timeRule(collectInfoChangeBos.get(index).getUpdateTime2() * 1000);
                            esfEstateListApi.setCestcodes(collectInfoChangeBos.get(index).getCollectInfoBo().getCollectValue());
                            esfEstateListApi.setType("");
                            esfEstateListApi.setPosttype("");
                            esfEstateListApi.startRequest();
                        } else {
                            time = DateUtil.timeRule(collectInfoChangeBos.get(index).getUpdateTime2() * 1000);
                            price = priceTransformate(index);
                            postListApi.setPostIds(collectInfoChangeBos.get(index).getCollectInfoBo().getCollectValue());
                            postListApi.startRequest();
                        }
                    } else {
                        atv_news_desc.setText("");
                        atv_date.setText("");
                    }
                } else {
                    EsfEstateDo esfEstateDo = esfEstateDos.get(0);
                    estateName = esfEstateDo.getName();
                    refreshDynamic();
                }
            }

            @Override
            public void onErrorResponse(VolleyError error) {
            }
        });
        esfEstateListApi.setType("");
        esfEstateListApi.setPosttype("");
    }


    private void refreshDynamic() {
        atv_date.setText(time);
        switch (collectInfoChangeBos.get(index).getChangeType()) {
            case "pricechange":
                atv_news_desc.setText(String.format(Locale.CHINA, "您关注的房源%s%s%s啦", postName, roomCount, price));
                break;
            case "online":
                atv_news_desc.setText(String.format(Locale.CHINA, "您关注的房源%s%s已停售", postName, roomCount));
                break;
            case "chengjiao":
                atv_news_desc.setText(String.format(Locale.CHINA, "您关注的房源%s%s已成交", postName, roomCount));
                break;
            case "estcount":
                atv_news_desc.setText(String.format(Locale.CHINA, "您关注的小区%s新上一套房源", estateName));
                break;
        }
    }

    private void cleanDynamic() {
        atv_news_desc.setText("");
        atv_date.setText("");
        SprfUtil.setBoolean(getActivity(), String.format(Locale.CHINA, "%s_%s", AppConstant.CityCode, SprfConstant.JPUSH_NEW_MESSAGE), false);
        EventBus.getDefault().post(new JPushMessage(""));
    }

    public void refreshUi() {
        collectInfoChangeApi.startRequest();
    }

    @Override
    public void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }

    /**
     * 城市变更
     */
    public void cityChange() {
        checkConversation();
        refreshUi();
    }

    /**
     * 连接状态改变
     */
    @Subscribe
    public void onEventMainThread(RongConnectStatus rongConnectStatus) {
        switch (rongConnectStatus.getStatus()) {
            case 0://连接成功
                checkConversation();
                break;
            default:
                checkConversation();
                break;
        }
    }

    /**
     * 用户状态改变
     */
    @Subscribe
    public void onEventMainThread(UserOperate userOperate) {
        switch (userOperate.getStatus()) {
            case 0:
                checkConversation();
                cleanDynamic();
                break;
            case 1:
                checkConversation();
                refreshUi();
                break;
            default:
                break;
        }
    }

    /**
     * 会话状态更新[位置\未读消息]
     */
    @Subscribe
    public void onEventMainThread(ConversationUpdate conversationUpdate) {
        EventBus.getDefault().post(new JPushMessage(""));
        switch (conversationUpdate.getStatus()) {
            case 0:
                updateSingleConversation(conversationUpdate.getTargetId(), true);
                break;
            case 1:
                updateSingleConversation(conversationUpdate.getTargetId(), false);
                break;
            default:
                break;
        }
    }

    /**
     * 新消息
     */
    @Subscribe
    public void onEventMainThread(RongReceiveMessage receiveMessage) {
        if (receiveMessage != null &&
                receiveMessage.getMessage() != null) {
            updateSingleConversation(receiveMessage.getMessage().getTargetId(), true);
        }
    }

    /**
     * 检查会话列表
     */
    private void checkConversation() {
        if (AppConstant.IsLogin) {
            bizUnit();//聊天是否开启
        } else {
            clearConversation();
        }
    }

    /**
     * 初始化会话
     */
    private void initConversation() {
        if (RongIMClient.getInstance() != null) {
            RongIMClient.getInstance().getConversationList(new RongIMClient.ResultCallback<List<Conversation>>() {
                @Override
                public void onSuccess(List<Conversation> conversations) {
                    conversationList.clear();
                    if (conversations != null) {
                        for (Conversation conversation : conversations) {
                            if (conversation.getTargetId().contains(AppConstant.CityCode)) {//只保留当前城市的
                                conversationList.add(conversation);
                            }
                        }
                    }
                    adapter.notifyDataSetChanged();
                }

                @Override
                public void onError(RongIMClient.ErrorCode errorCode) {
                    conversationList.clear();
                    adapter.notifyDataSetChanged();
                }
            }, Conversation.ConversationType.PRIVATE);
        }
    }

    /**
     * 更新独立的Conversation
     *
     * @param updatePosition 是否更新位置
     */
    private void updateSingleConversation(String targetId, final boolean updatePosition) {
        if (RongIMClient.getInstance() != null) {
            RongIMClient.getInstance().getConversation(Conversation.ConversationType.PRIVATE, targetId, new RongIMClient.ResultCallback<Conversation>() {
                @Override
                public void onSuccess(Conversation result) {
                    int index = 0;
                    int size = conversationList.size();
                    boolean isInList = false;//是否在列表中
                    for (int i = 0; i < size; i++) {
                        if (result.getTargetId().equals(conversationList.get(i).getTargetId())) {
                            isInList = true;
                            index = i;
                            conversationList.remove(i);
                            conversationList.add(updatePosition ? 0 : i, result);
                            break;
                        }
                    }
                    if (isInList) {//会话是否已在列表中
                        adapter.notifyItemChanged(index);
                        if (updatePosition &&
                                index > 0) {
                            adapter.notifyItemMoved(index, 0);
                        }
                    } else {
                        conversationList.add(0, result);
                        adapter.notifyItemInserted(0);
                    }
                }

                @Override
                public void onError(RongIMClient.ErrorCode errorCode) {

                }
            });
        }
    }

    /**
     * 清除某个消息
     */
    private void clearMessage(String targetId) {
        if (RongIMClient.getInstance() != null) {
            RongIMClient.getInstance().removeConversation(
                    Conversation.ConversationType.PRIVATE,
                    targetId, new RongIMClient.ResultCallback<Boolean>() {
                        @Override
                        public void onSuccess(Boolean aBoolean) {

                        }

                        @Override
                        public void onError(RongIMClient.ErrorCode errorCode) {

                        }
                    });
            RongIMClient.getInstance().clearMessages(
                    Conversation.ConversationType.PRIVATE,
                    targetId, new RongIMClient.ResultCallback<Boolean>() {
                        @Override
                        public void onSuccess(Boolean aBoolean) {

                        }

                        @Override
                        public void onError(RongIMClient.ErrorCode errorCode) {

                        }
                    });
        }
    }

    /**
     * 清空会话,用户未登录或聊天功能未开启
     */
    private void clearConversation() {
        conversationList.clear();
        adapter.notifyDataSetChanged();

    }

    /**
     * 新通知
     */
    @Subscribe
    public void onEventMainThread(JPushMessage jPushMessage) {
        if (jPushMessage != null) {
            if ("tomain".equals(jPushMessage.getMessage())) {
            } else {
                img_news_point.setVisibility(SprfUtil.getBoolean(getContext(),
                        String.format(Locale.CHINA, "%s_%s", AppConstant.CityCode, SprfConstant.JPUSH_NEW_MESSAGE), false) ?
                        View.VISIBLE : View.GONE);
                refreshUi();
            }
        }
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.rl_news:
                startActivityForResult(new Intent(getActivity(), EstateNewsActivity.class), CommonConstant.REQ_DYNAMIC);
                break;
            default:
                break;
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (Activity.RESULT_OK == resultCode) {
            switch (requestCode) {
                case CommonConstant.REQ_DYNAMIC:
                    refreshUi();
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 获取配置信息
     */
    private void bizUnit() {
        RxDataBase.getBizUnit()
                .compose(this.<BizUnitDo>bindUntilEvent(FragmentEvent.DESTROY))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<BizUnitDo>() {
                    @Override
                    public void call(BizUnitDo bizUnitDo) {
                        if (bizUnitDo.isShowTalk()) {
                            initConversation();
                        } else {
                            clearConversation();
                        }
                    }
                });
    }

    /**
     * 保存聊天用户信息
     */
    private void saveTargetStaff(StaffDo staffDo) {
        RxDataBase.saveStaff(staffDo)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(this.<Void>bindUntilEvent(FragmentEvent.DESTROY))
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {

                    }
                });
    }

    /**
     * 价格转换工具
     */
    private String priceTransformate(int index) {
        String price = "";
        if (TextUtils.isDigitsOnly(collectInfoChangeBos.get(index).getChangeMsg2().replace("-", ""))) {
            int intPrice = Integer.parseInt(collectInfoChangeBos.get(index).getChangeMsg2());
            if (intPrice > 0) {//涨
                int up = intPrice;
                price = Math.abs(up) >= 10000 ?
                        String.format(Locale.CHINA, "上涨%d万", up / 10000) :
                        String.format(Locale.CHINA, "上涨%d", up);
            } else {
                int down = intPrice * -1;
                price = Math.abs(down) >= 10000 ?
                        String.format(Locale.CHINA, "下跌%d万", down / 10000) :
                        String.format(Locale.CHINA, "下跌%d", down);
            }
        }
        return price;
    }

}
